﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Farigola.Engine.Factories;
using Farigola.Engine.SystemData.Entity.Type;
using Farigola.Engine.SystemData.Entity;
using Farigola.Engine.SystemData.Entity.inst;

namespace Farigola.Engine.SystemData
{
    /// <summary>
    /// manager of all data of the system: 
    /// built-in and user defined type and entities, 
    /// are defined in the scope/responsability of the workspace.
    /// </summary>
    public class SystemDataMgr
    {
        /// <summary>
        /// The factory to build all data object.
        /// </summary>
        private Factory _factory;

        /// <summary>
        /// The unique errors manager of the engine application.
        /// Provided to main object in the engine (workspace, project,...).
        /// </summary>
        //private ErrorMgr _errorMgr;

        /// <summary>
        /// Manager of tasks activity in the application (trace)
        /// Manage alos errors occurs in the engine.
        /// </summary>
        private AppActivityMgr _appActivityMgr;

        /// <summary>
        /// Manager of builtin type entities.
        /// </summary>
        private TypeMgr _typeMgr;

        /// <summary>
        /// Manager of builtin instances entities.
        /// <summary>
        // todo: EntInstMgr

        /// <summary>
        /// Manager of ... todo: dataValue? processingUnit?...
        /// <summary>
        // todo: DataValueMgr

        /// <summary>
        /// the entity type folder,
        /// its in the list be also here
        /// because used very often, so  can be accessed more quickly.
        /// </summary>
        private EntTypeFolder _entTypeFolder;

        /// <summary>
        /// the entity type string,
        /// its in the list be also here
        /// because used very often, so  can be accessed more quickly.
        /// </summary>
        private EntTypeString _entTypeString;

        /// <summary>
        /// the entity type struct list,
        /// its in the list be also here
        /// because used very often, so  can be accessed more quickly.
        /// </summary>
        private EntTypeStructList _typeStructList;

        // others ent type often used like: int, double, list,...

        //---------------------------------------------------------------------
        /// <summary>
        /// Constructor.
        /// </summary>
        /// <param name="factory"></param>
        public SystemDataMgr(Factory factory, AppActivityMgr appActivityMgr)
        {
            //_factory = Factory.GetFactory();
            _factory = factory;

            _appActivityMgr = appActivityMgr;
        }

        //---------------------------------------------------------------------
        /// <summary>
        /// Check the workspace internal content, after init.
        /// a basic check, if an error occurs, return false.
        /// </summary>
        /// <returns></returns>
        public bool CheckInternal()
        {
            if (_factory == null)
                return false;

            if (_typeMgr == null)
                return false;

            return true;
        }

        //=====================================================================
        #region get/set methods.
        #endregion

        //=====================================================================
        #region Find methods.

        //---------------------------------------------------------------------
        /// <summary>
        /// Return the ent type, by the name.
        /// todo: rename -> getEntTypeByName()
        /// </summary>
        /// <param name="name"></param>
        /// <returns></returns>
        public EntTypeBase FindEntTypeByName(String name)
        {
            return _typeMgr.FindEntTypeByName(name);
        }

        //---------------------------------------------------------------------
        /// <summary>
        /// Return the ent type, by the id.
        /// todo: rename -> getEntTypeById()
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public EntTypeBase FindEntTypeById(EntityId id)
        {
            return _typeMgr.FindEntTypeById(id);
        }

        #endregion

        //---------------------------------------------------------------------
        /// <summary>
        /// Return the EntTypeFolder.
        /// </summary>
        /// <returns></returns>
        public EntTypeFolder GetEntTypeFolder()
        {
            if (_entTypeFolder == null)
                return null;

            return _entTypeFolder;
        }

        //---------------------------------------------------------------------
        /// <summary>
        /// Return the EntTypeString.
        /// </summary>
        /// <returns></returns>
        public EntTypeString GetEntTypeString()
        {
            if (_entTypeString == null)
                return null;

            return _entTypeString;
        }

        //---------------------------------------------------------------------
        /// <summary>
        /// Return the EntityId representing the EntTypeFolder.
        /// </summary>
        /// <returns></returns>
        public EntityId GetEntTypeFolderEntityId()
        {
            if (_entTypeFolder == null)
                return null;

            return _entTypeFolder.GetId();
        }


        //=====================================================================
        // Is methods.

        //---------------------------------------------------------------------
        /// <summary>
        /// Return true if the entity type is an entity type folder.
        /// 
        /// Compare directly the internal id, 
        /// not the object EntityId or the object EntTypeFolder.
        /// </summary>
        /// <param name="entType"></param>
        /// <returns></returns>
        public bool IsEntTypeFolder(EntTypeBase entType)
        {
            if (entType == null)
                return false;

            return _entTypeFolder.GetId().IdAreEquals(entType.GetId());
        }

        //---------------------------------------------------------------------
        /// <summary>
        /// Return true if the entity type is an entity type basic.
        ///
        /// </summary>
        /// <param name="entType"></param>
        /// <returns></returns>
        public bool IsEntTypeBasic(EntTypeBase entType)
        {
		    if(entType==null)
			    return false;
		
		    // check the type
		    if(entType is EntTypeBasicBase)
			    return true;
		
		    return true;
	    }

        //---------------------------------------------------------------------
        /// <summary>
        /// Return true if the entity type is an entity type string.
        /// </summary>
        /// <param name="entType"></param>
        /// <returns></returns>
        public bool IsEntTypeString(EntTypeBase entType)
        {
		    if(entType==null)
			    return false;
		
		    // check the type
		    if(entType is EntTypeString)
			    return true;
		
		    return true;
	    }

        //---------------------------------------------------------------------
        /// <summary>
        /// Return true if the entity type is an entity type class base.
        /// </summary>
        /// <param name="entType"></param>
        /// <returns></returns>
        public bool IsEntTypeClassBase(EntTypeBase entType)
        {
		    if(entType==null)
			    return false;
		
		    // check the type
		    if(entType is EntTypeClassBase)
			    return true;
		
		    return true;		
	    }

        //---------------------------------------------------------------------
        /// <summary>
        /// Return true if the entity type is an entity type class.
        /// </summary>
        /// <param name="entType"></param>
        /// <returns></returns>
        public bool IsEntTypeClass(EntTypeBase entType)
        {
		    if(entType==null)
			    return false;
		
		    // check the type
		    if(entType is EntTypeClass)
			    return true;
		
		    return true;		
	    }

        //---------------------------------------------------------------------
        /// <summary>
        /// Return true if the entity type is an entity type class anonym.
        /// </summary>
        /// <param name="entType"></param>
        /// <returns></returns>
        public bool IsEntTypeClassAnonym(EntTypeBase entType)
        {
		    if(entType==null)
			    return false;
		
		    // check the type
		    if(entType is EntTypeClassAnonym)
			    return true;
		
		    return true;		
	    }

        //---------------------------------------------------------------------
        /// <summary>
        /// Return true if the inst is an instance string.
        /// </summary>
        /// <param name="inst"></param>
        /// <returns></returns>
        public bool IsTypeString(EntInstBase inst)
        {
		    if(inst==null)
			    return false;
		
		    if(inst is EntInstString)
			    return true;

		    return true;
	    }

        //---------------------------------------------------------------------
        /// <summary>
        /// Return true if the inst is an instance class.
        /// </summary>
        /// <param name="inst"></param>
        /// <returns></returns>
        public bool IsTypeClass(EntInstBase inst)
        {
		    if(inst==null)
			    return false;
		
		    if(inst is EntInstClass)
			    return true;

		    return true;
	    }

        //---------------------------------------------------------------------
        /// <summary>
        /// Return true if the inst is an instance class anonym.
        /// </summary>
        /// <param name="inst"></param>
        /// <returns></returns>
        public bool IsTypeClassAnonym(EntInstBase inst)
        {
		    if(inst==null)
			    return false;
		
		    if(inst is EntInstClassAnonym)
			    return true;

		    return true;
	    }

        //=====================================================================
        #region Generals methods.

        //---------------------------------------------------------------------
        /// <summary>
        /// Create internal manager of types.
        /// </summary>
        /// <returns></returns>
        public bool Init()
        {
            _typeMgr = _factory.CreateTypeMgr();
            return true;
        }

        //---------------------------------------------------------------------
        /// <summary>
        /// Clear all data in the manager.
        /// </summary>
        public void clearAll()
        {

        }

        #endregion

        //=====================================================================
        #region Add type methods.

        //---------------------------------------------------------------------
        /// <summary>
        /// Save the built-in entity type folder.
        /// 
        /// only one instance exists.
        ///
        /// </summary>
        /// <param name="typeFolder"></param>
        /// <returns></returns>
        public bool AddEntTypeFolder(EntTypeFolder typeFolder)            
        {
            if (typeFolder == null)
                return false;

            // check if not already added
            if (_typeMgr.contains(typeFolder))
                return false;
            if (_entTypeFolder != null)
                return false;

            // ok, add it
            _typeMgr.Add(typeFolder);

            // save it (because used very often)
            _entTypeFolder = typeFolder;

            return true;
        }

        //---------------------------------------------------------------------
        /// <summary>
        /// Save the built-in entity type string.
        /// 
        /// only one instance exists.
        /// </summary>
        /// <param name="typeString"></param>
        /// <returns></returns>
        public bool AddEntTypeString(EntTypeString typeString)
        {
            if (typeString == null)
                return false;

            // check if not already added
            if (_typeMgr.contains(typeString))
                return false;
            if (_entTypeString != null)
                return false;

            // ok, add it
            _typeMgr.Add(typeString);

            // save it (because used very often)
            _entTypeString = typeString;

            return true;
        }

        //---------------------------------------------------------------------
        public bool AddEntTypeStructList(EntTypeStructList typeStructList)
        {
            if (typeStructList == null)
                return false;

            // check if not already added
            if (_typeMgr.contains(typeStructList))
                return false;
            if (_typeStructList != null)
                return false;

            // ok, add it
            _typeMgr.Add(typeStructList);

            // save it (because used very often)
            _typeStructList = typeStructList;

            return true;
        }

        #endregion
    }
}
